package gameBasicElements;

import java.io.Serializable;
import java.util.LinkedList;

/**
 * @author Tomasz Wiatrowski
 *
 */
public class ScoreBoard implements Serializable
{
	private static final long serialVersionUID = 1680963387493041196L;
	private double whitePlayerScore, blackPlayerScore;

	/**
	 * @param board Board
	 * @param pos Position
	 * @return 
	 */
	private PlayerColor getTerritory(Board board, Position pos){
		if(board.getPlayerColor(pos) != null)
			return board.getPlayerColor(pos);
		LinkedList<Position> queue = new LinkedList<Position>();
		boolean[][] visited = new boolean[board.getSize()][board.getSize()];
		boolean white, black;
		white = black = false;
		for(int i=0; i<board.getSize(); ++i)
			for(int j=0; j<board.getSize(); ++j)
				visited[i][j] = false;
		queue.add(pos);
		while(!queue.isEmpty()){
			Position temp = queue.getFirst();
			queue.removeFirst();
			visited[temp.getX()][temp.getY()] = true;
			for(Position neighbour : board.getNeighbours(temp)){
				if((!visited[neighbour.getX()][neighbour.getY()])&&(board.getPlayerColor(neighbour) == null)){
					visited[neighbour.getX()][neighbour.getY()] = true;
					queue.add(neighbour);
				}
				if(board.getPlayerColor(neighbour) == PlayerColor.WHITE)
					white = true;
				else if(board.getPlayerColor(neighbour) == PlayerColor.BLACK)
					black = true;
			}
		}
		if(white == black)
			return null;
		if(white)
			return PlayerColor.WHITE;
		return PlayerColor.BLACK;
	}
	
	/**
	 * @param board Board
	 * adds points for territory to players' scores
	 */
	private void getTerritoryScore(Board board){
		for(int i=0; i<board.getSize(); ++i)
			for(int j=0; j<board.getSize(); ++j){
				PlayerColor temp = getTerritory(board, new Position(i, j));
				if(temp == PlayerColor.WHITE)
					whitePlayerScore += 1.0;
				else if(temp == PlayerColor.BLACK)
					blackPlayerScore += 1.0;
			}
	}
	
	/**
	 * @param board Board
	 * adds points for captives to players' scores
	 */
	private void getCaptivesScore(Board board){
		whitePlayerScore += board.captivesScore(PlayerColor.WHITE);
		blackPlayerScore += board.captivesScore(PlayerColor.BLACK);
	}
	
	/**
	 * @param board Board
	 * @param komi double
	 * @return ScoreBoard for board
	 */
	public ScoreBoard(Board board, double komi){
		whitePlayerScore = blackPlayerScore = 0;
		getTerritoryScore(board);
		getCaptivesScore(board);
		whitePlayerScore += komi;
	}
	
	/**
	 * @return white player's score
	 */
	public double getWhitePlayerScore()
	{
		return whitePlayerScore;
	}

	/**
	 * @return black player's score
	 */
	public double getBlackPlayerScore()
	{
		return blackPlayerScore;
	}
	
	
}
